package com.dkm.orproject.dkmoa.action;

import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSON;
import com.dkm.orproject.dkmoa.domain.OaJurisdiction;
import com.dkm.orproject.dkmoa.domain.OaLog;
import com.dkm.orproject.dkmoa.domain.OaPersonnel;
import com.dkm.orproject.dkmoa.domain.vo.OaAdressBookVo;
import com.dkm.orproject.dkmoa.service.OaPersonnelService;
import com.dkm.orproject.utils.jwt.jwtutils.TokenUtil;
import com.dkm.orproject.utils.jwt.login.UserLoginToken;
import com.dkm.orproject.utils.utils.IdToobtainUtils;
import com.dkm.orproject.utils.utils.ThreeVo;
import com.dkm.orproject.utils.utils.Tools;
import io.swagger.annotations.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;


/**
 *  @ClassName : OaPersonnelAction  //类名
 *  @Description : 人员  //描述 selectByDepartmentId
 *  @Author : 石智诚  //作者
 *  @Date: 2020-07-30 09:28  //时间
 */
@Api(value = "用户操作Controller", tags = {"用户操作"})
@RestController
@RequestMapping("/OaPersonnelAction")
public class OaPersonnelAction {
    /**
     * 声明logger
     */
    private static final Logger logger = LoggerFactory.getLogger(OaPersonnelService.class);
    /**
     * 人员服务接口
     */
    @Resource
    OaPersonnelService personnelService;
    /**
     * 雪花算法
     */
    @Resource
    IdToobtainUtils utils;
    /**
     * 工具类
     */
    @Resource
    Tools tools;
    /**
     * 日志
     */
    OaLog log;
    /**
     * 登陆人
     */
    OaPersonnel person;

    /**
     * 回调map
     */
    Map<String, Object> map;
    /**
     * 行数
     */
    int row;

    /**
     * 用户登录
     *
     * @param personnel 人员的信息
     * @param session   信息
     * @return 0 登录失败,1 成功
     */
    @ApiOperation(value = "查询登录", notes = "登录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "personnelAccount", value = "用户名", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "personnelPwd", value = "密码", required = true, dataType = "String", paramType = "query"),
    })
    @ApiResponses({
            @ApiResponse(code = 200, message = "OK", response = OaPersonnel.class),
    })
    @GetMapping("isLogin")
    public Map<String, Object> isLogin(@ApiIgnore OaPersonnel personnel, HttpSession session, HttpServletRequest request) {
        Map<String, Object> map = new HashMap<>(16);
        log = new OaLog();
        try {
            //密码加密T
            personnel.setPersonnelPwd(Tools.password(personnel.getPersonnelPwd()));
            OaPersonnel serivceLogin = personnelService.isLogin(personnel);
            //判断是否为空
            if (ObjectUtils.isEmpty(serivceLogin)) {
                map.put("msg", "密码错误");
                return tools.rowMap(map, 0, null);
            }
            List<OaJurisdiction> jurisdictions = personnelService.selectByOj(serivceLogin.getPkPersonnelId());
            List<OaJurisdiction> memus = new ArrayList<>();
            List<OaJurisdiction> button = new ArrayList<>();
            for (OaJurisdiction jurisdiction : jurisdictions) {
                if ("1".equals(jurisdiction.getJurisdictionType())) {
                    memus.add(jurisdiction);
                } else {
                    button.add(jurisdiction);
                }
            }
            //增加日志
            log.setLogTitle("登录模块");
            log.setLogBody(JSON.toJSON(serivceLogin).toString());
            log.setLogIp(request.getRemoteAddr());
            log.setCreatedBy(serivceLogin.getPersonnelName());
            log.setLogType("1");
            tools.rowMap(map, 1, log);
            //生成token
            String jwtToken = TokenUtil.createJwtToken(serivceLogin);
            //把user 和token 放入session
            session.setAttribute("memus", memus);
            session.setAttribute("button", button);
            session.setAttribute("user", serivceLogin);
            session.setAttribute("token", jwtToken);
            map.put("token", jwtToken);
        } catch (Exception e) {
            e.printStackTrace();
            //增加日志
            log.setLogTitle("用户登录模块");
            log.setLogBody(e.getLocalizedMessage());
            log.setLogIp(request.getRemoteAddr());
            log.setCreatedBy(e.getMessage());
            log.setLogType("0");
            tools.errorMap(map, log);
        }
        return map;
    }

    /**
     * 查询关键字是否重复
     *
     * @param personnel 关键字或者人员ID
     * @param request   请求
     * @return 1和0
     */
    @UserLoginToken
    @GetMapping("selectAccount")
    public Map<String, Object> findByAccount(OaPersonnel personnel, HttpServletRequest request) {
        try {
            row = personnelService.findByAccount(personnel);
            tools.rowMap(this.map, row, log);
        } catch (Exception e) {
            addErrorLog(request, "关键字", e);
        }
        return map;
    }


    /**
     * 查询所有人员(下拉框)
     *
     * @param request 请求
     * @return id 和名字
     */
    @GetMapping("personnelFindByAll")
    public Map<String, Object> findByAll(HttpServletRequest request) {
        rowMap(request);
        try {
            List<OaPersonnel> all = personnelService.findByAll();
            return Tools.maps(all, null);
        } catch (Exception e) {
            addErrorLog(request, "人员查询", e);
        }
        return null;
    }

    /**
     * /**
     * 更新或者添加人员信息的
     *
     * @param personnel 更新或者添加人员信息的
     * @param request   请求
     * @return 成功与否
     */
    @PostMapping("addOrUpdate")
    @UserLoginToken
    public Map<String, Object> addOrUpdate(OaPersonnel personnel,
                                           HttpServletRequest request) {
        rowMap(request);
        if (ObjectUtils.isEmpty(personnel)) {
            return tools.rowMap(map, 0, log);
        }
        try {
            if (personnel.getPkPersonnelId() != null && personnel.getPkPersonnelId() > 0) {
                //添加更新人和时间
                personnel.setUpdatedBy(person.getPersonnelName());
                personnel.setUpdatedTime(new Date());
                personnel.setPersonnelPwd(Tools.password(personnel.getPersonnelPwd()));
                row = personnelService.updateByPrimaryKeySelective(personnel);
                log.setLogTitle("人员信息更新");
            } else {
                //id随机生成
                personnel.setPkPersonnelId(utils.getNumberId());
                personnel.setCreatedBy(person.getPersonnelName());
                row = personnelService.insertSelective(personnel);
                log.setLogTitle("人员增加模块");
            }
            log.setLogBody(JSON.toJSON(personnel).toString());
            log.setLogType("1");
            tools.rowMap(map, row, log);
        } catch (Exception e) {
            addErrorLog(request, "用户增加或者更新操作", e);
        }
        return map;
    }

    /**
     * 根据人员id查询的人员信息(编辑)
     *
     * @param pkPersonnelId 人员Id
     * @param request       请求
     * @return 人员的信息
     */
    @GetMapping("selectById/{pkPersonnelId}")
    @UserLoginToken
    public Map<String, Object> selectById(@PathVariable("pkPersonnelId") Long pkPersonnelId, HttpServletRequest request) {
        rowMap(request);
        try {
            OaPersonnel personnel = personnelService.selectByPrimaryKey(pkPersonnelId);
            map.put("data", personnel);
        } catch (Exception e) {
            addErrorLog(request, "根据id查询人员", e);
        }
        return map;
    }

    /**
     * 根据部门ID查询人员
     *
     * @param departmentId 部门Id
     * @param request      请求
     * @return 人员模型
     */
    @GetMapping("selectByDepartmentId/{departmentId}")
    @UserLoginToken
    public Map<String, Object> selectByDepartmentId(@PathVariable("departmentId") Long departmentId, HttpServletRequest request) {
        rowMap(request);
        try {
            List<OaPersonnel> oaPersonnel = personnelService.selectByDertment(departmentId, person.getPkPersonnelId());
            map.put("data", oaPersonnel);
            Tools.maps(oaPersonnel, 0L);
        } catch (Exception e) {
            addErrorLog(request, "根据部门id查询人员", e);
        }
        return map;
    }

    /**
     * 查看个人信息
     *
     * @param pkPersonnelId 人员Id
     * @param request       请求
     * @return 人员个人信息
     */
    @GetMapping("findById/{pkPersonnelId}")
    @UserLoginToken
    public Map<String, Object> findById(@PathVariable("pkPersonnelId") Long pkPersonnelId, HttpServletRequest request) {
        rowMap(request);
        try {
            OaPersonnel personnel = personnelService.selectByPersonId(pkPersonnelId);
            map.put("data", personnel);
        } catch (Exception e) {
            addErrorLog(request, "根据id查询人员", e);
        }
        return map;
    }

    /**
     * 逻辑删除
     *
     * @param pkPersonnelId 人员ID
     * @param request       操作的
     * @return 操作的结果
     */
    @PutMapping("updateById/{pkPersonnelId}")
    @UserLoginToken
    public Map<String, Object> updateById(@PathVariable("pkPersonnelId") Long pkPersonnelId, HttpServletRequest request) {
        rowMap(request);
        try {
            row = personnelService.updateById(pkPersonnelId, person.getPersonnelName());
            log.setLogTitle("删除模块");
            log.setLogBody(JSON.toJSON(row).toString());
            log.setLogType("1");
            tools.rowMap(map, row, log);
        } catch (Exception e) {
            addErrorLog(request, "删除模块", e);
        }
        return map;
    }

    /**
     * 人员物理删除
     *
     * @param pkPersonnelId 用户ID
     * @param request       操作的
     * @return 结果
     */
    @UserLoginToken
    @DeleteMapping("deletePersonnel/{pkPersonnelId}")
    public Map<String, Object> delete(@PathVariable("pkPersonnelId") Long pkPersonnelId, HttpServletRequest request) {
        rowMap(request);
        try {
            row = personnelService.deleteByPrimaryKey(pkPersonnelId);
            log.setLogTitle("删除模块");
            log.setLogBody(JSON.toJSON(row).toString());
            log.setLogType("1");
            tools.rowMap(map, row, log);
        } catch (Exception e) {
            addErrorLog(request, "用户删除模块", e);
        }
        return map;
    }

    /**
     * 流程id查询人员树
     *  @Author : 易嵘 //作者
     *  @Date: 2020-09-04 09:59  //时间
     *
     * @param flowId  流程id
     * @param request 服务器请求
     * @return 人员树
     */
    @UserLoginToken
    @GetMapping("/findTreePersons/{flowId}")
    public List<ThreeVo> findTreePersons(@PathVariable(value = "flowId", required = false) Long flowId, HttpServletRequest request) {
        try {
            if (flowId < 1L) {
                flowId = null;

            }
            return personnelService.treePersons(flowId);
        } catch (Exception e) {
            addErrorLog(request, "流程id查询", e);
        }
        return null;
    }

    /**
     * 流程id查询拥有入职流程审核的人员树
     *  @Author : 易嵘 //作者
     *  @Date: 2020-09-23 09:42  //时间
     *
     * @param flowId  流程id
     * @param request 服务器请求
     * @param wordKey 权限关键字
     * @return 人员树
     */
    @UserLoginToken
    @GetMapping("/findTreeEntryCheckPersons")
    public List<ThreeVo> findTreeEntryCheckPersons(Long flowId, String wordKey, HttpServletRequest request) {
        try {
            if (flowId < 1L) {
                flowId = null;
            }
            return personnelService.findTreeEntryCheckPersons(flowId, wordKey);
        } catch (Exception e) {
            addErrorLog(request, "流程id查询", e);
        }
        return null;
    }

    /**
     * 查询分页(总人数)
     *
     * @param personnel 用户信息
     * @param page      第几页
     * @param limit     返回的数据条数
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return 分页的数据和总数
     */
    @UserLoginToken
    @GetMapping("findAll")
    public Map<String, Object> findAll(OaPersonnel personnel,
                                       Integer page,
                                       Integer limit,
                                       String startTime,
                                       String endTime, HttpServletRequest request) {
        try {
            List<OaPersonnel> all = personnelService.findAll(personnel, page, limit, startTime, endTime);
            Long count = personnelService.rowCount(personnel, startTime, endTime);
            return Tools.maps(all, count);
        } catch (Exception e) {
            addErrorLog(request, "人员查询", e);
        }
        return null;
    }

    @GetMapping("test")
    public List<OaPersonnel> test() {
        List<OaPersonnel> test = personnelService.export();
        return test;
    }

    /**
     * /**
     * 将人员名单进行导出
     *
     * @param response 请求
     * @throws IOException 异常
     */
    @GetMapping("/export")
    public void export(HttpServletResponse response) throws IOException {
        // 这里注意 有同学反应使用swagger 会导致各种问题，请直接用浏览器或者用postman
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode("测试", "UTF-8").replace("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        EasyExcel.write(response.getOutputStream(), OaPersonnel.class).sheet("模板").doWrite(data());
    }


    /**
     * 批量逻辑删除
     *
     * @param ids     人员id的集合
     * @param request 请求
     * @return 删除的行数
     */
    @PostMapping("updateAll")
    @UserLoginToken
    public Map<String, Object> updateAll(@RequestParam(value = "ids[]", required = false) Long[] ids, HttpServletRequest request) {
        rowMap(request);
        List<Long> idssi;
        //id为空的情况下
        if (ObjectUtils.isEmpty(ids)) {
            logger.info("数组为空");
            return tools.rowMap(map, 0, null);
        } else {
            idssi = Arrays.asList(ids);
        }
        try {
            row = personnelService.updateAll(idssi, person.getPersonnelName());
            log.setLogTitle("人员逻辑删除");
            log.setLogBody(JSON.toJSON(idssi).toString());
            log.setLogType("1");
            tools.rowMap(map, row, log);
        } catch (Exception e) {
            addErrorLog(request, "人员逻辑删除", e);
        }
        return map;
    }

    /**
     * 投票需要的树
     *
     * @param request 请求
     * @return 集合
     */
    @UserLoginToken
    @GetMapping("/selectAll")
    public List<ThreeVo> selectAll(HttpServletRequest request) {
        try {
            return personnelService.selectAll();
        } catch (Exception e) {
            addErrorLog(request, "投票专用树", e);
        }
        return null;
    }

    /**
     * 批量删除
     *
     * @param ids     人员id的集合
     * @param request 请求
     * @return 是否删除的
     */
    @DeleteMapping("deleteAll")
    @UserLoginToken
    public Map<String, Object> deleteAll(@RequestParam(value = "ids[]", required = false) Long[] ids, HttpServletRequest request) {
        rowMap(request);
        List<Long> idss;
        if (ObjectUtils.isEmpty(ids)) {
            return tools.rowMap(map, 0, null);
        } else {
            idss = Arrays.asList(ids);
        }
        try {
            int deleteAll = personnelService.deleteAll(idss);
            log.setLogTitle("批量删除模块");
            log.setLogBody(JSON.toJSON(deleteAll).toString());
            log.setLogType("1");
            tools.rowMap(map, deleteAll, log);
        } catch (Exception e) {
            addErrorLog(request, "批量删除模块", e);
        }
        return map;
    }


    /**
     * 获得用户信息
     *
     * @param session 操作人的信息
     * @return 用户信息
     */
    @GetMapping("getUser")
    public OaPersonnel getUser(HttpSession session) {
        OaPersonnel personnel = (OaPersonnel) session.getAttribute("user");
        personnel.setPersonnelPwd("");
        if (ObjectUtils.isEmpty(personnel)) {
            personnel = new OaPersonnel();
            personnel.setPersonnelName("未登录");
            personnel.setIsRevision("9");
        }
        return personnel;
    }

    /**
     * 获得token的信息
     *
     * @param session 登录的信息
     * @return 人员模型
     */
    @GetMapping("getToken")
    public Map<String, Object> getToken(HttpSession session) {
        Map<String, Object> map = new HashMap<>(16);
        OaPersonnel personnel = (OaPersonnel) session.getAttribute("user");
        String token = (String) session.getAttribute("token");
        if (StringUtils.isEmpty(token) || ObjectUtils.isEmpty(personnel)) {
            map.put("code", 0);
        } else {
            map.put("code", 1);
            map.put("token", token);
        }
        return map;
    }

    @GetMapping("getMemus")
    public List<OaJurisdiction> getMemus(HttpSession session) {
        List<OaJurisdiction> jurisdictions = (List<OaJurisdiction>) session.getAttribute("memus");
        return jurisdictions;
    }

    @GetMapping("getButton")
    public List<OaJurisdiction> getButton(HttpSession session) {
        List<OaJurisdiction> jurisdictions = (List<OaJurisdiction>) session.getAttribute("button");
        return jurisdictions;
    }

    /**
     * 注销
     *
     * @param session 用户的信息
     * @return 1
     */
    @UserLoginToken
    @GetMapping("/logout")
    public int logout(HttpSession session) {
        session.removeAttribute("user");
        session.removeAttribute("token");
        return 1;
    }

    /**
     * 通讯录
     *
     * @param request 请求
     * @return
     */
    @UserLoginToken
    @GetMapping("/addressBook")
    private List<OaAdressBookVo> addressBook(HttpServletRequest request) {
        try {
            return personnelService.addressBook();
        } catch (Exception e) {
            addErrorLog(request, "通讯录", e);

        }
        return null;
    }

    private void addErrorLog(HttpServletRequest request, String title, Exception e) {
        e.printStackTrace();
        OaPersonnel personnel = (OaPersonnel) request.getSession().getAttribute("user");
        log = new OaLog();
        log.setLogType("0");
        log.setLogBody(e.getLocalizedMessage());
        log.setLogTitle(title);
        log.setLogIp(request.getRemoteAddr());
        if (ObjectUtils.isEmpty(personnel)) {
            log.setCreatedBy(personnel.getPersonnelName());
        }
        tools.errorMap(log);
    }


    /**
     * 简化代码
     *
     * @param request 请求
     */
    private void rowMap(HttpServletRequest request) {
        //新建返回Map模型
        map = new HashMap<>(16);
        //获取登陆人信息
        person = (OaPersonnel) request.getSession().getAttribute("user");
        //新建日志
        log = new OaLog();
        //得到ip
        log.setLogIp(request.getRemoteAddr());
        //登陆人名称
        log.setCreatedBy(person.getPersonnelName());
    }

    /**
     * 为数据导出做准备
     *
     * @return 集合
     */
    private List<OaPersonnel> data() {
        List<OaPersonnel> list = new ArrayList<OaPersonnel>();
        List<OaPersonnel> all = personnelService.export();
        for (OaPersonnel oaPersonnel : all) {
            OaPersonnel personnel = new OaPersonnel();
            personnel.setPersonnelName(oaPersonnel.getPersonnelName());
            personnel.setPersonnelAccount(oaPersonnel.getPersonnelAccount());
            personnel.setPersonnelPhone(oaPersonnel.getPersonnelPhone());
            personnel.setOrganizationType(oaPersonnel.getOrganizationType());
            personnel.setCompanyName(oaPersonnel.getCompanyName());
            personnel.setCreatedBy(oaPersonnel.getCreatedBy());
            personnel.setPkPersonnelId(oaPersonnel.getPkPersonnelId());
            personnel.setOrganizationType(oaPersonnel.getOrganizationType());
            list.add(personnel);
        }
        return list;
    }
}
